package rbac.dao.impl;

import java.util.Collection;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import rbac.dao.UserDao;
import rbac.entity.RbacUser;


/**
 * RBAC 用户管理 DAO 实现类.
 * 
 * @author Huadi
 * @author Zoufengyang
 */
@Repository("userDao")
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor={Exception.class})
	public RbacUser getUser(String userName) {
		Query query = getSession().getNamedQuery("rbacUser.getRbacUserByName");
		query.setString("name", userName);

		return (RbacUser) query.uniqueResult();
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor={Exception.class})
	public RbacUser getUser(Integer id) {
		return (RbacUser) getHibernateTemplate().get(RbacUser.class, id);
	}

	@SuppressWarnings("unchecked")
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor={Exception.class})
	public List<RbacUser> getAllUsers() {
		Query query = getSession().getNamedQuery("rbacUser.getAllRbacUsers");

		return query.list();
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor={Exception.class})
	public void delete(RbacUser user) {
		getHibernateTemplate().delete(user);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor={Exception.class})
	public void delete(Integer userId) {
		Query query = getSession().getNamedQuery("rbacUser.deleteRbacUserById");
		query.setInteger("id", userId);
		query.executeUpdate();
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor={Exception.class})
	public void save(RbacUser user) {
		getHibernateTemplate().save(user);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor={Exception.class})
	public void update(RbacUser user) {
		getHibernateTemplate().update(user);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<RbacUser> getUsers(Collection<Integer> userIds) {
		Criteria criteria = getSession().createCriteria(RbacUser.class);
		criteria.add(Restrictions.in("id", userIds));
		return criteria.list();
	}

	// TODO: service 层尚未应用到此方法，应继续完善 service 层代码尽量使用此方法更新。
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor={Exception.class})
	public void addUsersToUserGroup(Collection<Integer> addUserIds,
			Collection<Integer> deleteUserIds, Integer userGroupId) {
		// XXX: 删除关系表中的实体关系记录, 此处与实体表耦合.
		Query deleteQuery = getSession()
				.createSQLQuery(
						"DELETE FROM t_rbac_user_group WHERE user_id = :userId AND group_id = :userGroupId");
		deleteQuery.setInteger("userGroupId", userGroupId);
		for (Integer userId : deleteUserIds) {
			deleteQuery.setInteger("userId", userId);
			deleteQuery.executeUpdate();
		}

		Query insertQuery = getSession()
				.createSQLQuery(
						"INSERT INTO t_rbac_user_group(rbac_user_id,user_group_id) VALUES (:userId,:userGroupId)");
		insertQuery.setInteger("userGroupId", userGroupId);
		for (Integer userId : addUserIds) {
			insertQuery.setInteger("userId", userId);
			insertQuery.executeUpdate();
		}
	}

}
